﻿/*  Kiva.NET
 *  Copyright (c) 2009 Arun Kumar 
 *  middleforce@gmail.com
 */
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace KivaLibrary
{   /// <summary>
    /// Factory Class to generate API calls and process XML responses
    /// </summary>
    public static class KivaFactory
    {
        #region "Lender Functions"
        /// <summary>
        /// Retrieves Lender information for a single Lender UID
        /// </summary>
        /// <param name="uid">Lender's UID</param>
        /// <returns>KivaLender</returns>
        public static KivaLender GetLender(string uid)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLenderURL(uid)));
                XElement lenderXML =
                    (from el in responseXML.Elements("lenders").Elements("lender")
                     select el).First();
                return KivaXMLMapper.MapLender(lenderXML);
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving lender.", "GetLender", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves Lender information by muiltple Lender UIDs
        /// </summary>
        /// <param name="uid">Comma-separated list of Lender UIDs</param>
        /// <returns>KivaPage of Lenders</returns>
        public static List<KivaLender> GetLenders(string uid)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLenderURL(uid)));
                List<KivaLender> lenders = new List<KivaLender>();
                foreach (XElement lenderXML in responseXML.Element("lenders").Elements("lender"))
                {
                    lenders.Add(KivaXMLMapper.MapLender(lenderXML));
                }
                return lenders;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving lenders.", "GetLenders", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves Loans for a Lender
        /// </summary>
        /// <param name="uid">Lender UID</param>
        /// <returns>KivaPage of Loans</returns>
        public static KivaPage GetLenderLoans(string uid, int pageNumber)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLenderLoansURL(uid, pageNumber)));
                KivaPage loans = new KivaPage();
                loans = KivaXMLMapper.MapPage(responseXML.Element("paging"));
                foreach (XElement loanXML in responseXML.Element("loans").Elements("loan"))
                {
                    loans.PageItems.Add(KivaXMLMapper.MapLoan(loanXML));
                }
                return loans;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving lender loans.", "GetLenderLoans", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves first page of Loans for a Lender
        /// </summary>
        /// <param name="uid">Lender UID</param>
        /// <returns>KivaPage of Loans</returns>
        public static KivaPage GetLenderLoans(string uid)
        {
            return GetLenderLoans(uid, 1);
        }
        #endregion
        #region "Partner Functions"
        public static KivaPage GetPartners() { return GetPartners(1); }
        public static KivaPage GetPartners(int pageNumber)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetAllPartnersURL(pageNumber)));
                KivaPage partners = new KivaPage();
                partners = KivaXMLMapper.MapPage(responseXML.Element("paging"));
                foreach (XElement partnerXML in responseXML.Element("partners").Elements("partner"))
                {
                    partners.PageItems.Add(KivaXMLMapper.MapPartner(partnerXML));
                }
                return partners;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving partners.", "GetPartners", ex);
                return null;
            }
        }
        #endregion
        #region "Loan Functions"
        /// <summary>
        /// Retrieves Loan Information by Loan IDs
        /// </summary>
        /// <param name="id">Comma-separated list of Loan IDs</param>
        /// <returns>KivaLoan</returns>
        public static List<KivaLoan> GetLoans(string id)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLoanURL(id)));
                List<KivaLoan> loans = new List<KivaLoan>();
                foreach (XElement loanXML in responseXML.Element("loans").Elements("loan"))
                {
                    loans.Add(KivaXMLMapper.MapLoan(loanXML));
                }
                return loans;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving loans.", "GetLoans", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves Newest Loans
        /// </summary>
        public static KivaPage GetNewestLoans(int pageNumber)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetNewestLoansURL(pageNumber)));
                KivaPage loans = new KivaPage();
                loans = KivaXMLMapper.MapPage(responseXML.Element("paging"));
                foreach (XElement loanXML in responseXML.Element("loans").Elements("loan"))
                {
                    loans.PageItems.Add(KivaXMLMapper.MapLoan(loanXML));
                }
                return loans;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving newest loans.", "GetNewestLoans", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves Newest Loans
        /// </summary>
        public static KivaPage GetNewestLoans()
        {
            return GetNewestLoans(1);
        }
        /// <summary>
        /// Retrieves Lenders for a Loan
        /// </summary>
        /// <param name="id">Loan ID</param>
        /// <returns>KivaPage of Loans</returns>
        public static KivaPage GetLoanLenders(string id, int pageNumber)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLoanLendersURL(id, pageNumber)));
                KivaPage lenders = new KivaPage();
                lenders = KivaXMLMapper.MapPage(responseXML.Element("paging"));
                foreach (XElement lenderXML in responseXML.Element("lenders").Elements("lender"))
                {
                    lenders.PageItems.Add(KivaXMLMapper.MapLender(lenderXML));
                }
                return lenders;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving loan lenders.", "GetLoanLenders", ex);
                return null;
            }
        }
        /// <summary>
        /// Retrieves filtered list of Loans. Pass an empty string to ignore any filter.
        /// </summary>
        /// <param name="status">The status of the loans to return any of [fundraising, funded, in_repayment, paid, defaulted] </param>\
        /// <param name="gender">Matches the gender of the borrower(s) requesting the loan any of [male,female] </param>
        /// <param name="sector">Matches sector based on the name of a sector.</param>
        /// <param name="countryCode">Matches valid two character ISO codes representing the origin of the loans.</param>
        /// <param name="region">Matches two character codes representing Kiva lending regions. Any of [na,ca,sa,af,as,me,ee] </param>
        /// <param name="partnerID">Matches partners based on id.</param>
        /// <param name="query">General query string applied to activity, city or country, partner, or business name.</param>
        /// <returns>KivaPage of Loans</returns>
        public static KivaPage GetLoans(string status, string gender, string sector, string region,
                    string countryCode, string partnerID, string query, int pageNumber)
        {
            try
            {
                XElement responseXML = XElement.Load((KivaURLFactory.GetLoansURL(status, gender, sector, region,
                     countryCode, partnerID, query, pageNumber)));
                KivaPage loans = new KivaPage();
                loans = KivaXMLMapper.MapPage(responseXML.Element("paging"));
                foreach (XElement loanXML in responseXML.Element("loans").Elements("loan"))
                {
                    loans.PageItems.Add(KivaXMLMapper.MapLoan(loanXML));
                }
                return loans;
            }
            catch (System.Exception ex)
            {
                ErrorFactory.ErrorHandler("Error while retrieving loans.", "GetLoans", ex);
                return null;
            }
        }


        #endregion


    }
}
